package com.violet.rabbitmq.config;

import com.rabbitmq.client.Channel;
import com.violet.rabbitmq.constant.RabbitEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.Resource;

import static com.violet.rabbitmq.config.PrimaryRabbitMqConfig.PRIMARY_FACTORY;
import static com.violet.rabbitmq.constant.RabbitEnum.EXCHANGE_METER_DATA_REPORT;
import static com.violet.rabbitmq.constant.RabbitEnum.QUEUE_METER_STATUS;
import static org.springframework.amqp.core.ExchangeTypes.FANOUT;

/**
 * @Author: wqf
 * @Date: 2024/08/13
 * @Description:
 */
@Slf4j
@Configuration
public class RabbitMqQueenConfig {

    @Resource(name = PRIMARY_FACTORY)
    private ConnectionFactory primaryConnectionFactory;

    /**
     * 数据上报交换机和队列绑定
     */
    @Bean
    public String meterStatusBinding() {
        try {
            Channel channel = primaryConnectionFactory.createConnection().createChannel(false);
            queueBind(channel,
                    EXCHANGE_METER_DATA_REPORT,
                    //广播
                    FANOUT,
                    QUEUE_METER_STATUS);
        } catch (Exception e) {
            log.error("==============队列创建失败=============={}", QUEUE_METER_STATUS, e);
            return QUEUE_METER_STATUS.getValue();
        }
        return QUEUE_METER_STATUS.getValue();
    }

    /**
     * 方法描述: 创建队列
     *
     * @param channel      mq连接
     * @param exchangeName 交换机名称
     * @param exchangeType 交换机类型
     * @param queueName    队列名称
     * @param routerName   路由键名称
     * @return com.rabbitmq.client.Channel
     * @author wqf
     * @date 2024/8/13 10:35
     */
    private void queueBind(Channel channel,
                           RabbitEnum exchangeName,
                           String exchangeType,
                           RabbitEnum queueName,
                           RabbitEnum routerName) throws Exception {
        // 1. exchange:交换机名称 2. type:交换机类型 DIRECT("direct"),：定向, FANOUT("fanout"),：扇形（广播），发送消息到每一个与之绑定队列。
        // TOPIC ("topic"),通配符的方式 HEADERS("headers");参数匹配
        // 3. durable:是否持久化 4. autoDelete:自动删除 5. internal：内部使用。 一般false 6. arguments：参数
        channel.exchangeDeclare(exchangeName.getValue(), exchangeType, true, false, false, null);
        //创建队列Queue 参数1：队列名称 参数2：是否定义持久化队列 参数3：是否独占本次连接 参数4：是否在不使用的时候自动删除队列 参数5：队列其它参数
        channel.queueDeclare(queueName.getValue(), true, false, false, null);
        //绑定队列 queueBind(String queue, String exchange, String routingKey)
        //参数： 1. queue：队列名称 2. exchange：交换机名称 3. routingKey：路由键，绑定规则,如果交换机的类型为fanout ，routingKey设置为""
        channel.queueBind(queueName.getValue(), exchangeName.getValue(), routerName.getValue());
    }


    /**
     * 方法描述: 创建队列
     *
     * @param channel      mq连接
     * @param exchangeName 交换机名称
     * @param exchangeType 交换机类型
     * @param queueName    队列名称
     * @return com.rabbitmq.client.Channel
     * @author wqf
     * @date 2024/8/13 10:35
     */
    private void queueBind(Channel channel,
                           RabbitEnum exchangeName,
                           String exchangeType,
                           RabbitEnum queueName) throws Exception {
        // 1. exchange:交换机名称 2. type:交换机类型 DIRECT("direct"),：定向, FANOUT("fanout"),：扇形（广播），发送消息到每一个与之绑定队列。
        // TOPIC ("topic"),通配符的方式 HEADERS("headers");参数匹配
        // 3. durable:是否持久化 4. autoDelete:自动删除 5. internal：内部使用。 一般false 6. arguments：参数
        channel.exchangeDeclare(exchangeName.getValue(), exchangeType, true, false, false, null);
        //创建队列Queue 参数1：队列名称 参数2：是否定义持久化队列 参数3：是否独占本次连接 参数4：是否在不使用的时候自动删除队列 参数5：队列其它参数
        channel.queueDeclare(queueName.getValue(), true, false, false, null);
        //绑定队列 queueBind(String queue, String exchange, String routingKey)
        //参数： 1. queue：队列名称 2. exchange：交换机名称 3. routingKey：路由键，绑定规则,如果交换机的类型为fanout ，routingKey设置为""
        channel.queueBind(queueName.getValue(), exchangeName.getValue(), "");
    }


}
